#include "Graphcalculator.h"
#include "ui_Graphcalculator.h"
#include<QGraphicsLineItem>
//具体逻辑有待进一步完成

Graphcalculator::Graphcalculator(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Graphcalculator),
    scene(new QGraphicsScene(this)),
    axesDrawn(false) // 初始化坐标轴未绘制
{
    ui->setupUi(this);
    ui->plotWidget->setScene(scene);
    ui->plotWidget->setRenderHint(QPainter::Antialiasing);  // 设置抗锯齿，提高绘图质量

    // 绘制坐标轴
    drawAxes();

    // 翻转Y轴
    QTransform transform = ui->plotWidget->transform();
    transform.scale(1, -1);
    ui->plotWidget->setTransform(transform);

    // 连接按钮点击信号到槽
   connect(ui->buttonPlot, &QPushButton::clicked, this, &Graphcalculator::plotFunction);
   connect(ui->buttonClear, &QPushButton::clicked, this, &Graphcalculator::clearPlot);

   symbolTable.add_variable("x", x);
   expression.register_symbol_table(symbolTable);

}

Graphcalculator::~Graphcalculator()
{
    delete ui;
}

void Graphcalculator::drawAxes() {
    // 定义坐标轴范围
    double axisLength = 200;  // 可以根据需要调整
    double tickSize = 5;

    // 绘制x轴
    scene->addLine(-axisLength, 0, axisLength, 0, QPen(Qt::black, 2));
    // 绘制y轴
    scene->addLine(0, -axisLength, 0, axisLength, QPen(Qt::black, 2));

    // 绘制x轴刻度
    for (int i = -axisLength; i <= axisLength; i += 10) {
        scene->addLine(i, -tickSize, i, tickSize, QPen(Qt::black, 2));
    }

    // 绘制y轴刻度
    for (int i = -axisLength; i <= axisLength; i += 10) {
        scene->addLine(-tickSize, i, tickSize, i, QPen(Qt::black, 2));
    }

    // 绘制x轴箭头
    QPolygonF arrowHeadX;
    arrowHeadX << QPointF(axisLength, 0)
               << QPointF(axisLength - 5, -5)
               << QPointF(axisLength - 5, 5);
    scene->addPolygon(arrowHeadX, QPen(Qt::black), QBrush(Qt::black));

    // 绘制y轴箭头
    QPolygonF arrowHeadY;
    arrowHeadY << QPointF(0, axisLength)
               << QPointF(-5, axisLength - 5)
               << QPointF(5, axisLength - 5);
    scene->addPolygon(arrowHeadY, QPen(Qt::black), QBrush(Qt::black));

    // 适应视图
    ui->plotWidget->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);
}



void Graphcalculator::plotFunction() {
    QString input = ui->lineEditExpression->text().trimmed();

    // 检查是否包含 'y='，如果包含，则移除
    if (input.startsWith("y=")) {
        input = input.mid(2).trimmed(); // 从 y= 后开始截取字符串
    }

    // 创建符号表和表达式
    exprtk::symbol_table<double> symbol_table;
    double x = 0.0; // 定义x变量并初始化
    symbol_table.add_variable("x", x);
    symbol_table.add_constants(); // 添加常数，如 e, pi 等

    exprtk::expression<double> expression;
    expression.register_symbol_table(symbol_table);

    exprtk::parser<double> parser;
    if (!parser.compile(input.toStdString(), expression)) {
        qDebug() << "表达式解析失败: " << input;
        ui->labelStatus->setText("表达式解析失败: " + input); // 更新状态信息
        return;
    } else {
        ui->labelStatus->setText("表达式解析成功。"); // 更新状态信息为成功
    }

    double xMin = -100, xMax = 100, xStep = 0.1;
    QVector<QPointF> points;

    for (x = xMin; x <= xMax; x += xStep) {
        // 直接更新x的值，因为它已经被引用绑定到符号表中
        double y = expression.value(); // 使用更新的x值计算y值
        points.push_back(QPointF(x, y));
    }

    scene->clear(); // 清除旧的图形
    drawAxes(); // 绘制坐标轴

    for (int i = 0; i < points.size() - 1; ++i) {
        scene->addLine(points[i].x(), points[i].y(), points[i + 1].x(), points[i + 1].y(), QPen(Qt::blue, 2));
    }

}


void Graphcalculator::clearPlot() {
    // 只清除绘图项，不清除坐标轴
    foreach (QGraphicsItem *item, scene->items()) {
        QGraphicsLineItem* lineItem = dynamic_cast<QGraphicsLineItem*>(item);
        if (lineItem && lineItem->pen().color() != Qt::black) {
            scene->removeItem(lineItem);
            delete lineItem;
        }
    }
    ui->lineEditExpression->clear();
}

